/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 *
 * http://www.gnu.org/copyleft/gpl.html
 */

package l1j.server.server.clientpackets;

import java.util.logging.Logger;

import l1j.server.server.ClientThread;
import l1j.server.server.model.L1World;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.skill.L1SkillUse;
import l1j.server.server.serverpackets.S_ServerMessage;
import static l1j.server.server.model.skill.L1SkillId.*;

// Referenced classes of package l1j.server.server.clientpackets:
// ClientBasePacket

public class C_UseSkill extends ClientBasePacket {
	private static Logger _log = Logger.getLogger(C_UseSkill.class.getName());
	private static final String C_USE_SKILL = "[C] C_UseSkill";

	// skillLv+skillNoからsKillIdに変換する為の配列
	private static final int[][] SKILLID_ARRAYS = {
			{}, // skillLv:0
			// Regular Magic Lv1-10
			{ HEAL, LIGHT, SHIELD, ENERGY_BOLT, TELEPORT, ICE_DAGGER,
					WIND_CUTTER, HOLY_WEAPON }, // skillLv:1
			{ CURE_POISON, CHILL_TOUCH, CURSE_POISON, ENCHANT_WEAPON,
					DETECTION, DECREASE_WEIGHT, FIRE_ARROW, STALAC }, // skillLv:2
			{ LIGHTNING, TURN_UNDEAD, EXTRA_HEAL, CURSE_BLIND, BLESSED_ARMOR,
					FROZEN_CLOUD, WEAK_ELEMENTAL }, // skillLv:3
			{ FIREBALL, PHYSICAL_ENCHANT_DEX, WEAPON_BREAK, VAMPIRIC_TOUCH,
					SLOW, EARTH_JAIL, COUNTER_MAGIC, MEDITATION }, // skillLv:4
			{ CURSE_PARALYZE, CALL_LIGHTNING, GREATER_HEAL, TAMING_MONSTER,
					REMOVE_CURSE, CONE_OF_COLD, MANA_DRAIN, DARKNESS }, // skillLv:5
			{ CREATE_ZOMBIE, PHYSICAL_ENCHANT_STR, HASTE, CANCELLATION,
					ERUPTION, SUNBURST, WEAKNESS, BLESS_WEAPON }, // skillLv:6
			{ HEAL_ALL, ICE_LANCE, SUMMON_MONSTER, HOLY_WALK, TORNADO,
					GREATER_HASTE, BERSERKERS, DISEASE }, // skillLv:7
			{ FULL_HEAL, FIREWALL, BLIZZARD, INVISIBILITY, RESURRECTION,
					EARTHQUAKE, LIFE_STREAM, SILENCE }, // skillLv:8
			{ LIGHTNING_STORM, FOG_OF_SLEEPING, SHAPE_CHANGE, IMMUNE_TO_HARM,
					MASS_TELEPORT, FIRE_STORM, DECAY_POTION, COUNTER_DETECTION }, // skillLv:9
			{ CREATE_MAGICAL_WEAPON, METEOR_STRIKE, GREATER_RESURRECTION,
					MASS_SLOW, DISINTEGRATE, ABSOLUTE_BARRIER, ADVANCE_SPIRIT,
					FREEZING_BLIZZARD }, // skillLv:10
			// Knight skills
			{ 0, 0, 0, 0, 0, 0, SHOCK_STUN, REDUCTION_ARMOR }, // skillLv:11
			{ BOUNCE_ATTACK, SOLID_CARRIAGE, COUNTER_BARRIER }, // skillLv:12
			// Dark Spirit Magic
			{ BLIND_HIDING, ENCHANT_VENOM, SHADOW_ARMOR, BRING_STONE,
					MOVING_ACCELERATION, BURNING_SPIRIT, DARK_BLIND,
					VENOM_RESIST }, // skillLv:13
			{ DOUBLE_BRAKE, UNCANNY_DODGE, SHADOW_FANG, FINAL_BURN,
					DRESS_MIGHTY, DRESS_DEXTERITY, DRESS_EVASION }, // skillLv:14
			// Royal Magic
			{ TRUE_TARGET, GLOWING_AURA, SHINING_AURA, CALL_CLAN, BRAVE_AURA,
					RUN_CLAN }, // skillLv:15
			{}, // skillLv:16
			// Spirit Magic
			{ RESIST_MAGIC, BODY_TO_MIND, TELEPORT_TO_MATHER, TRIPLE_ARROW,
					ELEMENTAL_FALL_DOWN, COUNTER_MIRROR }, // skillLv:17
			{ CLEAR_MIND, RESIST_ELEMENTAL }, // skillLv:18
			{ RETURN_TO_NATURE, BLOODY_SOUL, ELEMENTAL_PROTECTION, FIRE_WEAPON,
					WIND_SHOT, WIND_WALK, EARTH_SKIN, ENTANGLE }, // skillLv:19
			{ ERASE_MAGIC, LESSER_ELEMENTAL, FIRE_BLESS, STORM_EYE, EARTH_BIND,
					NATURES_TOUCH, EARTH_BLESS, AQUA_PROTECTER }, // skillLv:20
			{ AREA_OF_SILENCE, GREATER_ELEMENTAL, BURNING_WEAPON,
					NATURES_BLESSING, CALL_OF_NATURE, STORM_SHOT, WIND_SHACKLE,
					IRON_SKIN }, // skillLv:21
			{ EXOTIC_VITALIZE, WATER_LIFE, ELEMENTAL_FIRE, STORM_WALK,
					POLLUTE_WATER, STRIKER_GALE, SOUL_OF_FLAME, ADDITIONAL_FIRE } // skillLv:22
	};

	public C_UseSkill(byte abyte0[], ClientThread client) throws Exception {
		super(abyte0);
		int i = readC();
		int skillLv = i + 1;
		int skillNo = readC();
		String charName = null;
		String message = null;
		int targetId = 0;
		int targetX = 0;
		int targetY = 0;
		if (abyte0.length > 4) {
			try {
				if (skillLv == 15 && skillNo == 3 // コールクラン
						|| skillLv == 15 && skillNo == 5) { // ランクラン
					charName = readS();
				} else if (skillLv == 15 && skillNo == 0) { // トゥルーターゲット
					targetId = readD();
					targetX = readH();
					targetY = readH();
					message = readS();
				} else if (skillLv == 1 && skillNo == 4 // テレポート
						|| skillLv == 9 && skillNo == 4) { // マステレポート
					int bookmarkMapId = readH();
					targetId = readD();
				} else {
					targetId = readD();
					targetX = readH();
					targetY = readH();
				}
			} catch (Exception e) {
				// _log.log(Level.SEVERE, "", e);
			}
		}

		L1PcInstance pc = client.getActiveChar();

		if (pc.isTeleport()) { // テレポート処理中
			return;
		}
		if (pc.isDead()) {
			return;
		}

		if (pc.hasSkillEffect(ABSOLUTE_BARRIER)) { // アブソルート バリアの解除
			pc.killSkillEffectTimer(ABSOLUTE_BARRIER);
			pc.startHpRegeneration();
			pc.startMpRegeneration();
		}
		pc.killSkillEffectTimer(MEDITATION);

		try {
			int skillId = SKILLID_ARRAYS[skillLv][skillNo];
			if (skillId == 58 || skillId == 63) { // ファイアーウォール、ライフストリーム
				targetX = targetId & 0x0000ffff;
				targetY = (targetId & 0xffff0000) >>> 16;
				targetId = 0;
			}
			if ((skillId == 116 || skillId == 118) // コールクラン、ランクラン
					&& charName != null) {
				boolean isCallClan = false;
				for (L1PcInstance clanPc : L1World.getInstance()
						.getAllPlayers()) {
					if (clanPc.getName().toLowerCase().equals(
							charName.toLowerCase())) {
						if (pc.getClanid() == clanPc.getClanid()) {
							isCallClan = true;
							targetId = clanPc.getId();
						}
						break;
					}
				}
				if (!isCallClan) {
					pc.sendPackets(new S_ServerMessage(414)); // 同じ血盟員ではありません。
					return;
				}
			}
			L1SkillUse l1skilluse = new L1SkillUse();
			l1skilluse.handleCommands(client.getActiveChar(), skillId,
					targetId, targetX, targetY, message, 0,
					L1SkillUse.TYPE_NORMAL);

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public String getType() {
		return C_USE_SKILL;
	}
}
